home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
ORBIT_SO
/
ORBIT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-19
|
5KB
|
250 lines
/* Copyright 1987 */
/* David Palmer */
/* Mail code 220-47 */
/* California Institute Of Technology */
/* Uses EasyDialog.c (also ⌐ 1987 By David Palmer) */
/* Duplication, modification, and examination allowed on a */
/* non-commercial basis only. Commercial use prohibited */
/* without prior written agreement with the author. (This */
/* includes sale by for-profit companies, and use as an */
/* inducement to buy something.) */
#include <quickdraw.h>
#include <WindowMgr.h>
#include "orbit.h"
#include <EventMgr.h>
#include <stdio.h>
#define G 6.67e-11 /* MKS */
#define NMAX 100 /* how many particles */
#define TRUE (-1)
#define FALSE 0
#define HUGE 1e4000
double sqrt();
double precision = 100;
double drawperiod = 86400;
double scale = 2083333333;
int trailstyle = 3;
int fcenter = TRUE;
int background = 1;
PARTICLE rgpa[NMAX]; /* All of the particles */
int cpa; /* number of particles */
int cparead;
int xzero;
int yzero;
int drawcode, erasecode;
double dt = 864;
double rmin;
double v2max;
main(argc, argv)
int argc;
char *argv[];
{
InitGraf (&thePort); /* initialize the screen */
InitFonts();
InitWindows();
InitMenus();
InitCursor(); /* make the arrow Cursor */
TEInit();
InitDialogs(0L);
DoIt();
}
CenterParticles(ppa, cpa)
PARTICLE *ppa;
int cpa;
{
int i, j;
double p[NDIMS]; /* total momentum */
double mx[NDIMS]; /* first moment */
double m=0;
for (j = 0 ; j < NDIMS ; j++) {
p[j] = 0;
mx[j] = 0;
}
for (i = 0 ; i < cpa ; i++) {
m += ppa[i].m;
for (j = 0 ; j < NDIMS ; j++) {
mx[j] += ppa[i].m * ppa[i].x[j];
p[j] += ppa[i].p[j];
}
}
if (m == 0) /* can happen with negative and positive masses */
return;
for (j = 0 ; j < NDIMS ; j++) {
mx[j] /= m;
p[j] /= m; /* velocity of center of mass */
}
for (i = 0; i < cpa ; i++)
for (j = 0 ; j < NDIMS ; j++) {
ppa[i].x[j] -= mx[j];
ppa[i].p[j] -= ppa[i].m * p[j];
ppa[i].xt[j] = ppa[i].x[j];
}
}
SetPoint(ppa)
PARTICLE *ppa;
{
ppa->pt.h = xzero + ppa->x[0] / scale;
ppa->pt.v = yzero - ppa->x[1] / scale;
}
Interact(ppa1, ppa2)
PARTICLE *ppa1, *ppa2;
{
float ftot, f[NDIMS];
double r2, r;
double d[NDIMS];
int i;
r2 = 0;
for (i = 0 ; i < NDIMS ; i++) {
d[i] = ppa1->xt[i] - ppa2->xt[i];
r2 += d[i]*d[i];
}
r = sqrt(r2);
if (rmin > r)
rmin = r;
ftot = G * ppa1->m * ppa2->m / r2;
for (i = 0 ; i < NDIMS ; i++) {
f[i] = ftot * d[i]/r;
ppa1->f[i] -= f[i];
ppa2->f[i] += f[i];
}
}
Propagate(ppa, odt, dt)
PARTICLE *ppa;
double odt, dt;
{
double v, a;
double step, sesquistep, step2, sesquistep2;
double v2;
int i;
step = odt; step2 = 0.5 * odt *odt;
sesquistep = odt + 0.5 * dt; sesquistep2 = 0.5*sesquistep*sesquistep;
v2 = 0;
for (i = 0 ; i < NDIMS ; i++) {
v = ppa->p[i] / ppa->m;
a = ppa->f[i] / ppa->m;
ppa->xt[i] = ppa->x[i] + (sesquistep * v) + sesquistep2 * a;
ppa->x[i] += (step * v) + step2 * a;
ppa->p[i] += step * ppa->f[i];
ppa->f[i] = 0;
v2 += v*v;
}
if (v2max < v2)
v2max = v2;
}
DrawPath(ppa)
PARTICLE *ppa;
{
switch (trailstyle) {
case dot:
PenMode(erasecode);
MoveTo(ppa->pt.h, ppa->pt.v);
LineTo(ppa->pt.h, ppa->pt.v); /* Keep going */
case dottrain:
PenMode(drawcode);
SetPoint(ppa);
MoveTo(ppa->pt.h, ppa->pt.v);
LineTo(ppa->pt.h, ppa->pt.v);
break;
case linetrail:
MoveTo(ppa->pt.h, ppa->pt.v);
PenMode(drawcode);
SetPoint(ppa);
LineTo(ppa->pt.h, ppa->pt.v);
break;
default:
break;
}
}
DoIt()
{
int i, j;
double t, odt;
static int tlast;
int fdraw;
int whichbutton;
EventRecord theEvent;
xzero = screenBits.bounds.right/2;
yzero = screenBits.bounds.bottom/2;
while (TRUE) {
cpa = 0;
if (0 == GetParams())
exit(0);
do {
whichbutton = GetInit(&rgpa[cpa]);
if (whichbutton != 3) { /* if not the END button */
cpa++;
}
} while (whichbutton == 1);
if (fcenter)
CenterParticles(&rgpa, cpa);
for (i = 0 ; i < cpa ; i++) {
SetPoint(&rgpa[i]);
}
PenNormal();
PaintRect(&thePort->portRect);
if (background) { /* background is not black */
drawcode = notPatCopy;
erasecode = patCopy;
} else {
InvertRect(&thePort->portRect);
drawcode = patCopy;
erasecode = notPatCopy;
}
PenMode(drawcode);
HideCursor();
while (!Button()) {
if (tlast != (int)(t/drawperiod)) {
tlast = t/drawperiod;
fdraw = TRUE;
} else
fdraw = FALSE;
rmin = HUGE;
for (i = 0 ; i < cpa ; i++) {
for (j = i+1 ; j < cpa ; j++) {
Interact(&rgpa[i], &rgpa[j]);
}
}
t += dt;
odt = dt;
if (v2max != 0 && rmin != HUGE)
dt = rmin/(sqrt(v2max)*precision);
if (dt > 2*odt) /* limit growth of timestep */
dt = 2*odt;
v2max = 0;
for (i = 0 ; i < cpa ; i++) {
Propagate(&rgpa[i], odt, dt);
if (fdraw)
DrawPath(&rgpa[i]);
}
GetNextEvent(0xffff, &theEvent);
}
ShowCursor();
}
}